<?php

/**
 * Albireo Kernel
 *
 * @copyright  Copyright (c) 2010 Albireo Solutions
 * @package    Kernel
 */
 
namespace KernelModule\LogsModule\PhpModule;

use Nette\Object;
use Nette\Environment;
use Nette\IO\SafeStream;

use Albireo\FileSystem\File;
use Albireo\FileSystem\FileNotFoundException;

use KernelModule\LogsModule\LogsException;

/**
 * Kernel PHP Error searcher
 *
 * @author Pavel
 */

class Search extends Base {

    /**
     * @param String $formatedDate in the format "2010-09-15"
     * @return integer number of the line just after the searched date
     */
    public function findPosition($formatedDate) {
        if (($date = strtotime($formatedDate))) {
            try {
                $this->initializeLogFile("clean");
            } catch (LogsInitializeException $e) {
                throw new LogsException($e);
            }
            return $this->binarySearch(strtotime($formatedDate));
        }
    }

    /**
     * Classical binary search in the file of clean PHP logs. When the file
     * pointer is not moved in the next step, the cycle finishes and returns
     * the "parametrized" pointer position, which means simple filesize - pointer.
     *
     * @param int $timestamp datetime we wish to search
     * @return int position from the END of the file (filesize - pointer position).
     */
    private function binarySearch($timestamp) {
        $displayer = new Display();
        $min = 0;
        $max = $this->clean->getFileSize();
        $last = 0;

        do {
            $last = $this->clean->getPointerPosition();
            $this->clean->movePointerToPosition(($max + $min) / 2);
            $line = $this->clean->getCurrentLine();
            $lineTimestamp = $displayer->retrieveDate($line);
            if ($lineTimestamp >= $timestamp) {
                $max = $this->clean->getPointerPosition();
            } else {
                $min = $this->clean->getPointerPosition();
            }
        } while ($last != $this->clean->getPointerPosition());
        return $this->clean->getFileSize() - $max;
    }

}